// Code file original author: Martin Lapierre, http://devinstinct.com

using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;

namespace Microsoft.Practices.EnterpriseLibrary.Validation.Tests.Validators
{
	/// <summary>
	/// Tests <see cref="TypeValidatorAttribute"/>.
	/// </summary>
	[TestClass]
	public class TypeValidatorAttributeFixture
	{
		[TestMethod]
		public void ReturnsSuccessForValidType()
		{
			ObjectValidator<TestTargetC> validator = new ObjectValidator<TestTargetC>("ValidType");
			ValidationResults results = validator.Validate(new TestTargetC());

			Assert.IsTrue(results.IsValid);
		}

		[TestMethod]
		public void ReturnsFailureForInvalidType()
		{
			ObjectValidator<TestTargetC> validator = new ObjectValidator<TestTargetC>("InvalidType");
			ValidationResults results = validator.Validate(new TestTargetC());

			Assert.IsFalse(results.IsValid);
		}

		[TestMethod]
		public void ReturnsFailureForInvalidInheritedType()
		{
			ObjectValidator<TestTargetC> validator = new ObjectValidator<TestTargetC>("InvalidInheritedType");
			ValidationResults results = validator.Validate(new TestTargetC());

			Assert.IsFalse(results.IsValid);
		}

		[TestMethod]
		public void ReturnsSuccessForValidDerivedType()
		{
			ObjectValidator<TestTargetC> validator = new ObjectValidator<TestTargetC>("ValidDerivedType");
			ValidationResults results = validator.Validate(new TestTargetC());

			Assert.IsTrue(results.IsValid);
		}

		[TestMethod]
		public void NegatedReturnsFailureForValidDerivedType()
		{
			ObjectValidator<TestTargetC> validator = new ObjectValidator<TestTargetC>("NegatedValidDerivedType");
			ValidationResults results = validator.Validate(new TestTargetC());

			Assert.IsFalse(results.IsValid);
		}

		/// <summary>
		/// Test target A for this fixture.
		/// </summary>
		private class TestTargetA
		{
		}

		/// <summary>
		/// Test target B for this fixture.
		/// </summary>
		private class TestTargetB
			 : TestTargetA
		{
		}

		/// <summary>
		/// Test target C for this fixture.
		/// </summary>
		private class TestTargetC
		{
			[TypeValidator(typeof(TestTargetA), Ruleset = "ValidType")]
			[TypeValidator(typeof(string), Ruleset = "InvalidType")]
			[TypeValidator(typeof(TestTargetB), Ruleset = "InvalidInheritedType")]
			public TestTargetA a = new TestTargetA();

			[TypeValidator(typeof(TestTargetA), Ruleset = "ValidDerivedType")]
			[TypeValidator(typeof(TestTargetA), Ruleset = "NegatedValidDerivedType", Negated = true)]
			public TestTargetB b = new TestTargetB();
		}
	}
}
